package org.onvivals.app.ai.asr;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.nls.client.protocol.InputFormatEnum;
import com.alibaba.nls.client.protocol.NlsClient;
import com.alibaba.nls.client.protocol.SampleRateEnum;
import com.alibaba.nls.client.protocol.asr.SpeechTranscriber;
import com.alibaba.nls.client.protocol.asr.SpeechTranscriberListener;
import com.alibaba.nls.client.protocol.asr.SpeechTranscriberResponse;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 实时语音识别
 */
public class SpeechTranslationService {
	private String appKey;
	private String accessToken;
	private String channel;
	NlsClient client;

	public static Map<String, Object> transcriberMap = new ConcurrentHashMap<>(32);

	public static Map<String, StringBuffer> textMap = new ConcurrentHashMap<>();

	public SpeechTranslationService(String appKey, String token) {
		this.appKey = appKey;
		this.accessToken = token;
		client = NlsClientService.getNlsClient();
	}

	public SpeechTranslationService(String appKey, String token, String channel) {
		this.appKey = appKey;
		this.accessToken = token;
		client = NlsClientService.getNlsClient();
		this.channel = channel;
	}

	public SpeechTranscriberListener getTranscriberListener() {
		SpeechTranscriberListener listener = new SpeechTranscriberListener() {
			//识别出中间结果.服务端识别出一个字或词时会返回此消息.仅当setEnableIntermediateResult(true)时,才会有此类消息返回
			@Override
			public void onTranscriptionResultChange(SpeechTranscriberResponse response) {
				// 重要提示： task_id很重要，是调用方和服务端通信的唯一ID标识，当遇到问题时，需要提供此task_id以便排查
				//System.out.println("onTranscriptionResultChange:" + "name: " + response.getName() +
				//        //状态码 20000000 表示正常识别
				//        ", status: " + response.getStatus() +
				//        //句子编号，从1开始递增
				//        ", index: " + response.getTransSentenceIndex() +
				//        //当前的识别结果
				//        ", result: " + response.getTransSentenceText() +
				//        //当前已处理的音频时长，单位是毫秒
				//        ", time: " + response.getTransSentenceTime());
			}

			@Override
			public void onTranscriberStart(SpeechTranscriberResponse response) {
				System.out.println("onTranscriberStart:" + "task_id: " + response.getTaskId() +
						"name: " + response.getName() +
						", status: " + response.getStatus());
			}

			@Override
			public void onSentenceBegin(SpeechTranscriberResponse response) {
				System.out.println("onSentenceBegin:" + "task_id: " + response.getTaskId() +
						"name: " + response.getName() +
						", status: " + response.getStatus());
			}

			//识别出一句话.服务端会智能断句,当识别到一句话结束时会返回此消息
			@Override
			public void onSentenceEnd(SpeechTranscriberResponse response) {
				if (textMap.get(channel) != null) {
					StringBuffer append = textMap.get(channel).append(response.getTransSentenceText());
					textMap.put(channel, append);
				}else {
					textMap.put(channel, new StringBuffer(response.getTransSentenceText()));
				}
				// 重要提示： task_id很重要，是调用方和服务端通信的唯一ID标识，当遇到问题时，需要提供此task_id以便排查
				System.out.println("onSentenceEnd:" + "name: " + response.getName() +
						//状态码 20000000 表示正常识别
						", status: " + response.getStatus() +
						//句子编号，从1开始递增
						", index: " + response.getTransSentenceIndex() +
						//当前的识别结果
						", result: " + response.getTransSentenceText() +
						//置信度
						", confidence: " + response.getConfidence() +
						//开始时间
						", begin_time: " + response.getSentenceBeginTime() +
						//当前已处理的音频时长，单位是毫秒
						", time: " + response.getTransSentenceTime() +
						//关键词
						", words: " + response.getWords());
			}

			//识别完毕
			@Override
			public void onTranscriptionComplete(SpeechTranscriberResponse response) {
				System.out.println("onTranscriptionComplete:" + "task_id: " + response.getTaskId() +
						", name: " + response.getName() +
						", status: " + response.getStatus());
			}

			@Override
			public void onFail(SpeechTranscriberResponse response) {
				// 重要提示： task_id很重要，是调用方和服务端通信的唯一ID标识，当遇到问题时，需要提供此task_id以便排查
				System.out.println("onFail:" +
						"task_id: " + response.getTaskId() +
						//状态码 20000000 表示识别成功
						", status: " + response.getStatus() +
						//错误信息
						", status_text: " + response.getStatusText());
			}
		};

		return listener;
	}

	public void process(String channel, byte[] byteArray) {
		SpeechTranscriber transcriber = (SpeechTranscriber) transcriberMap.get(channel);
		try {
			if (ObjectUtil.isNull(transcriber)) {
				// 创建实例,建立连接
				transcriber = new SpeechTranscriber(client, getTranscriberListener());
				transcriber.setAppKey(appKey);
				// 输入音频编码方式
				transcriber.setFormat(InputFormatEnum.PCM);
				// 输入音频采样率
				transcriber.setSampleRate(SampleRateEnum.SAMPLE_RATE_16K);
				// 是否返回中间识别结果
				transcriber.setEnableIntermediateResult(false);
				// 是否生成并返回标点符号
				transcriber.setEnablePunctuation(true);
				// 是否将返回结果规整化,比如将一百返回为100
				transcriber.setEnableITN(false);
				//开启词模式
				transcriber.addCustomedParam("enable_words", true);
				//此方法将以上参数设置序列化为json发送给服务端,并等待服务端确认
				transcriber.start();
				transcriberMap.put(channel, transcriber);
			}
			transcriber.send(byteArray, byteArray.length);

		} catch (Exception e) {
			System.err.println(e.getMessage());
		}
	}

	public String text(String channel) {
		SpeechTranscriber transcriber = (SpeechTranscriber) transcriberMap.get(channel);
		if (transcriber!=null){
			try {
				transcriber.stop();
				transcriber.close();
				StringBuffer stringBuffer = textMap.get(channel);
				if (stringBuffer != null) {
					return stringBuffer.toString();
				}else {
					return "";
				}
			} catch (Exception e) {
				transcriberMap.remove(transcriber);
				throw new RuntimeException(e);
			}
		}
		return "";
	}

	public void shutdown() {
		client.shutdown();
	}

	public void close(String channel) {
		SpeechTranscriber transcriber = (SpeechTranscriber) transcriberMap.get(channel);
		if (transcriber!=null) {
			transcriberMap.remove(channel);
			textMap.remove(channel);
		}
	}


}
